package main

import (
	"bufio"
	"errors"
	"fmt"
	"go-web-learning/src/05_grpc/4_stream/stream"
	"google.golang.org/grpc"
	"google.golang.org/grpc/grpclog"
	"io"
	"net"
	"os"
)

func main() {
	bothStream()
}

type ServerStream struct {
}

func (ServerStream) Func(request *stream.Request, s stream.ServiceStream_FuncServer) error {
	fmt.Println("-----------------------------")
	fmt.Println("客户端传递的数据：", request)
	for i := 0; i < 10; i++ {
		s.Send(&stream.Response{Name: fmt.Sprintf("%s No.%02d", request.Name, i+1)})
	}
	return nil
}

func (ServerStream) Downloads(request *stream.Request, s stream.ServiceStream_DownloadsServer) error {
	fmt.Println("-----------------------------")
	fmt.Println("客户端传递的数据：", request)
	file, err := os.Open("src/05_grpc/4_stream/static/wget-log")
	if err != nil {
		return err
	}
	defer file.Close()

	for {
		buf := make([]byte, 200)
		_, err = file.Read(buf)
		if err == io.EOF {
			break
		} else if err != nil {
			return err
		}
		s.Send(&stream.FileResponse{Content: buf})
	}

	return nil
}

func serviceStream() {
	listen, err := net.Listen("tcp", ":8080")
	if err != nil {
		grpclog.Fatalf("Failed to listen: %s", err.Error())
	}
	defer listen.Close()
	server := grpc.NewServer()
	stream.RegisterServiceStreamServer(server, &ServerStream{})
	server.Serve(listen)
}

type ClientStreamServer struct {
}

func (ClientStreamServer) Uploads(s stream.ClientStream_UploadsServer) error {
	file, err := os.OpenFile("src/05_grpc/4_stream/static/pic_upload.png", os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0777)
	if !errors.Is(err, nil) {
		grpclog.Errorf("failed to create file: %s", err.Error())
		return err
	}
	defer file.Close()
	writer := bufio.NewWriter(file)
	for i := 0; ; i++ {
		recv, err := s.Recv()
		if errors.Is(err, io.EOF) {
			break
		} else if err != nil {
			return err
		}
		_, err = writer.Write(recv.Content)
		if err != nil {
			return err
		}
		fmt.Printf("第%02d次 传输数据长度: %d\n", i+1, len(recv.Content))
	}
	writer.Flush()
	err = s.SendAndClose(&stream.Response{Message: "ok"})
	if err != nil {
		return err
	}
	return nil
}

func clientStream() {
	listen, err := net.Listen("tcp", ":8080")
	if err != nil {
		grpclog.Fatalf("Failed to listen: %s", err.Error())
	}
	defer listen.Close()
	server := grpc.NewServer()
	stream.RegisterClientStreamServer(server, &ClientStreamServer{})
	server.Serve(listen)
}

type BothStream struct {
}

func (BothStream) Chat(s stream.BothStream_ChatServer) error {
	for i := 0; i < 10; i++ {
		fmt.Println("-------start-------")
		request, _ := s.Recv()
		fmt.Printf("receive client msg: %s\n", request.Message)
		s.Send(&stream.Response{Message: fmt.Sprintf("server msg No.%02d", i+1)})
		fmt.Println("--------end--------")
	}
	return nil
}

func bothStream() {
	listen, err := net.Listen("tcp", ":8080")
	if err != nil {
		grpclog.Fatalf("Failed to listen: %s", err.Error())
	}
	defer listen.Close()
	server := grpc.NewServer()
	stream.RegisterBothStreamServer(server, &BothStream{})
	server.Serve(listen)
}
